/*********************************************************
 * 初学之家(http://www.g2room.com)，提供Java、Javascript（js）、Jquery、
 * 等一些工具或常用功能的实现例子代码，希望能给初学者提供学习和工作上的帮助，
 * 也希望有想提供源代码的朋友能联系我，一起努力，提供更多、更全面、更详细的
 * 一些初学代码例子及经验，帮助更多的人。
 * 
 * 我的联系方式：E-Mail：g2room@163.com
 * 网址：http://www.g2room.com
 * QQ：天涯（1173930590）
 * QQ交流群：323642758
 * 
 * 本站内容为提供各种java、javascript(JS)常用的工具源代码、实例（示例）、
 * 基本配置、教程、手册等；目前Java代码提供的工具（或转换）例子代码如下：
 * BASE64转换工具、bytes相关操作、email收发、文件操作（读写、拷贝、遍历、
 * 多线程copy等）、json格式转换、日志（Log4j）操作工具、Lucene搜索引擎的
 * 创建索引和搜索、各种不同Map的使用、定时器（Quartz）的使用例子、Socket的
 * 连接传输数据例子、WebService的例子及一些常用的工具类如String、Date及
 * JDK自带的一些工具类及函数的使用例子。
 * 
 * 说明：如需直接使用本站的例子代码，请保留此说明
 * 
 ********************************************************/
package com.g2room.charset;

import java.io.UnsupportedEncodingException;

/**
 * 
 * 
 * @createTime: Jul 18, 2013 4:30:59 PM
 * @author: <a href="mailto:g2room@163.com">天涯</a>
 * @version: 0.1
 * @lastVersion: 0.1
 * @updateTime:
 * @updateAuthor: <a href="mailto:g2room@163.com">天涯</a>
 * @changesSum:
 * 
 */
public class UTF16 {
	public static void main(String[] args) throws UnsupportedEncodingException {
		String str = "商品：『能飞背单词小学英语词汇在线学』任选1学期课程份数：15份验证码：326372202132;385033326450;361728694007;364007890175;340703258269;317398626363;394093994317;348889543526;325584911083;302280279177;322593719518;399289087472;301568283243;378263651197;398577091001;有效期：2013-08-22至2013-11-15，购买后30天内完成课程开通（只需一分钟），在线登录即可学习，可永久使用进入以下地址:http://word.langfly.com/kt>>>输入验证码 根据提示即可开通课程学习。本团赠品由“佛山市天艺文化传播有限公司”提供，周一至周五48小时内发货，周末拍下的不发货，周一开始48小时内发货";
		// ------------编码
		// Java里使用的是UTF-16BE方式来存储数据的
//		for (int i = 0; i < str.length(); i++) {
//			String hexString = Integer.toHexString(str.charAt(i));
//			System.out.println(hexString.substring(0));
//		}
		System.out.println(str.getBytes("utf-8").length); // FE FF 4E 2D
		System.out.println(str.getBytes("utf-16").length); // FE FF 4E 2D
		/*
		 * 进行编码时，因为 UTF-16 编码方式本身未指定字节顺序标记，所以默认使用 Big Endian 字节 顺序编码，并将 Big
		 * Endian 字节顺序标记写入到流中，所以流前面多了 FE FF 二字节的高字节 顺序标记
		 */
//		System.out.println(byteToHex(str.getBytes("utf-8"))); // FE FF 4E 2D
//		System.out.println(byteToHex(str.getBytes("utf-16"))); // FE FF 4E 2D
//
//		/*
//		 * 进行编码时，UTF-16BE 和 UTF-16LE charset 不会将字节顺序标记写入到流中
//		 * 即它们所编出的码每个字符只占二个字节，要注意的是解码时要使用同样的编码 方式，不然会出现问题乱码
//		 */
//		System.out.println(byteToHex(str.getBytes("utf-16BE"))); // 4E 2D
//		System.out.println(byteToHex(str.getBytes("utf-16LE"))); // 2D 4E

		System.out.println(new String(new byte[] {0x05, 0x00, 0x03, 0x00, 0x00, 0x00}, "utf-16BE")); // 中
		// 使用 utf-16BE 对高字节序进行解码，忽略字节顺序标记，即不会将流前二字节内容看作字节序标记
//		System.out.println(new String(new byte[] { 0x4E, 0x2D }, "utf-16BE")); // 中
//		// 使用 utf-16LE 对低字节序进行解码，忽略字节顺序标记，即不会将流前二字节内容看作字节序标记
//		System.out.println(new String(new byte[] { 0x2D, 0x4E }, "utf-16LE")); // 中
//
//		// ------------解码
//
//		/*
//		 * 使用 utf-16 进行解码时，会根据流前两字节内部来确定是低还是高字节顺序，如果流的前两字节 内部不是 高字节序 FE
//		 * FF，也不是低字节序 FF FE时，则默认使用 高字节序 方式来解码
//		 */
//
//		// 因为0x4E,0x2D为“中”字的高字节表示，所以前面需要加上 FE FF 字节顺序标记来指示它
//		System.out.println(new String(new byte[] { (byte) 0xFE, (byte) 0xFF,
//				0x4E, 0x2D }, "utf-16")); // 中
//
//		// 因为0x2D,0x4E为“中”字的低字节表示，所以前面需要加上 FF FE 字节顺序标记来指示它
//		System.out.println(new String(new byte[] { (byte) 0xFF, (byte) 0xFE,
//				0x2D, 0x4E, }, "utf-16")); // 中
//
//		// 使用默认 高字节顺序 方式来解码，
//		System.out.println(new String(new byte[] { 0x4E, 0x2D }, "utf-16")); // 中
//
//		// 因为 0x2D,0x4E 为“中”的低字节序，但 utf-16 默认却是以 高字节序来解的，所以出现乱码
//		System.out.println(new String(new byte[] { 0x2D, 0x4E, }, "utf-16")); // ?
	}

	public static String byteToHex(byte[] bt) {
		StringBuilder sb = new StringBuilder(4);
		for (int b : bt) {
			sb.append(Integer.toHexString(b & 0x00FF | 0xFF00).substring(2, 4)
					.toUpperCase());
			sb.append(" ");
		}
		return sb.toString();
	}
}
